package com.mgface.completableFuture;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;

public class CompletableFutureTest {

	public static void main(String[] args) throws Exception {
		CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(1_000);
				String str = String.valueOf(ThreadLocalRandom.current().nextDouble());
				return str;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		});
		
		CompletableFuture<List<Integer>> future2 = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(1_000);
				List<Integer> list = Arrays.asList(4,5,6);
				return list;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		});
		
		CompletableFuture<List<Integer>> future3 = CompletableFuture.supplyAsync(() -> {
			try {
				Thread.sleep(1_000);
				List<Integer> list = Arrays.asList(1,2,3);
				return list;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		});

		Runnable run = () -> {
			try {
				String str = future.get();
				//String str =future.getNow("777");//Future还没完成将返回默认值
				System.out.println(Thread.currentThread().getName() + "---" + str);
			} catch (Exception e) {
				e.printStackTrace();
			}
		};
		
		Runnable run2 = ()->{
			CompletableFuture<Double> fun = future.handle((ok,error)->{
				if(ok!=null){
					//System.out.println("ok.....");
					return Double.valueOf(ok);
				}else{
					System.out.println("error:"+error);
					return 1.00;
				}
			});
			System.out.println("结果为:"+fun.join());
		};
		
//		new Thread(run).start();
//		new Thread(run).start();
		new Thread(run2).start();
		new Thread(run2).start();
		Thread.sleep(2_000);
		new CompletableFutureTest().say(future);
		
		CompletableFuture<Integer> result = future2.thenCombineAsync(future3, (a,b)->{
			return Stream.of(a,b).flatMap(num->num.stream()).map(e->Integer.valueOf(e)).reduce((c,d)->c+d).get();
		});
		System.out.println(result.join());
		future2.thenAcceptBoth(future3, (a,b)->{
			Integer value = Stream.of(a,b).flatMap(num->num.stream()).map(e->Integer.valueOf(e)).reduce((c,d)->c+d).get();
			System.out.println(value);
		});
		//System.out.println(future.completeExceptionally(new ArithmeticException("by zero")));
		//强迫这个future为这个值
		//future.obtrudeValue("555");
		//假如future还没有完成，放弃执行，直接采用默认值来执行
//		System.out.println(future.complete("123"));
//		CompletableFuture<Double> future2 = future.thenApplyAsync(Double::parseDouble).thenApplyAsync(e->Math.PI*e);
//		future2.thenAcceptAsync(e->{
//			try {
//				Thread.sleep(2_000);
//			} catch (Exception e1) {
//				// TODO Auto-generated catch block
//				e1.printStackTrace();
//			}
//			System.out.println("result:"+e);	
//		});
//		System.out.println("------");
		//System.out.println(future2.join());
		//如果尚未完成,导致调用get()和相关方法抛出的异常。
		//System.out.println(future.completeExceptionally(new ArithmeticException("by zero")));
		//返回一个新的CompletableFuture，这个future是已经完成的并且有给定值的
		//CompletableFuture.completedFuture("123");
		
	}
	
	public void say(CompletableFuture<String> future){
		 CompletableFuture<String>  cc = future.thenComposeAsync(this::calculate);
		 System.out.println(cc.join());
	}

	public CompletableFuture<String> calculate(String str){
		return CompletableFuture.completedFuture(str);
	}
}
